<!DOCTYPE html>
<html>
<head>
<title>The :unresolved pseudoclass matching with Document.querySelectorAll()</title>
<meta name="author" title="Aleksei Yu. Semenov" href="mailto:a.semenov@unipro.ru">
<meta name="author" title="Sergey G. Grekhov" href="mailto:sgrekhov@unipro.ru">
<meta name="assert" content="The :unresolved pseudoclass must match all custom elements whose created callback has not yet been invoked">
<link rel="help" href="http://www.w3.org/TR/custom-elements/#unresolved-element-pseudoclass">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="../../testcommon.js"></script>
<link rel="stylesheet" href="/resources/testharness.css">
</head>
<body>
<div id="log"></div>
<script>
test(function() {
    var doc = newHTMLDocument();
    doc.body.innerHTML = '<x-a></x-a>';
    var queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 1,
        'Unresolved custom element should be accessible by :unresolved pseudoclass');
    assert_equals(queryResult.item(0).localName, 'x-a',
        'Document.querySelectorAll(\':unresolved\') should return x-a element');
}, 'Test that single unresolved custom element is accessible ' +
    'by Document.querySelectorAll(\':unresolved\')');


test(function() {
    var doc = newHTMLDocument();
    doc.body.innerHTML = '<x-b></x-b>';
    var queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 1,
        'Unresolved custom element should be accessible by :unresolved pseudoclass');
    assert_equals(queryResult.item(0).localName, 'x-b',
        'Document.querySelectorAll(\':unresolved\') should return x-b element');

    doc.registerElement('x-b');
    queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 0,
        'Registered custom element should not be accessible by :unresolved pseudoclass');
}, 'Test that single registered custom element is not accessible by :unresolved');


test(function() {
    var doc = newHTMLDocument();
    doc.body.innerHTML = '<x-c></x-c><x-d></x-d>';
    var queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 2,
        'All unresolved custom element should be accessible by :unresolved pseudoclass');
    assert_equals(queryResult.item(0).localName, 'x-c',
        'First custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-c');
    assert_equals(queryResult.item(1).localName, 'x-d',
        'Second custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-d');

    doc.registerElement('x-c');
    queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 1,
        'Only unresolved custom elements should be accessible by :unresolved pseudoclass');
    assert_equals(queryResult.item(0).localName, 'x-d',
        'Custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-d');
}, 'If there are more than one unresolved custom element then all of them accessible ' +
    'by Document.querySelectorAll(\':unresolved\')');


test(function() {
    var doc = newHTMLDocument();
    var customElement = doc.createElement('x-e');
    doc.body.appendChild(customElement);
    var queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 1,
        'Unresolved custom element should be accessible by :unresolved pseudoclass');
    assert_equals(queryResult.item(0).localName, 'x-e',
        'Custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-e');
}, 'Unresolved custom element, created via Document.createElement(), should be ' +
    'accessible by Document.querySelectorAll(\':unresolved\')');


test(function() {
    var doc = newHTMLDocument();
    doc.body.innerHTML = '<x-f><x-g></x-g></x-f>';
    var queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 2,
        'All unresolved custom element should be accessible by :unresolved pseudoclass');
    assert_equals(queryResult.item(0).localName, 'x-f',
        'First custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-f');
    assert_equals(queryResult.item(1).localName, 'x-g',
        'Second custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-g');

    doc.registerElement('x-g');
    queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 1,
        'Only unresolved custom elements should be accessible by :unresolved pseudoclass');
    assert_equals(queryResult.item(0).localName, 'x-f',
        'Custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-f');
}, 'All unresolved custom element including nested ones are accessible ' +
    'by Document.querySelectorAll(\':unresolved\')');


testInIFrame('../../resources/x-element.html', function(doc) {
    var queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 1,
        'Unresolved custom element should be accessible by ' +
        'Document.querySelectorAll(\':unresolved\')');
    assert_equals(queryResult.item(0).localName, 'x-element',
        'Custom element returned by Document.querySelectorAll(\':unresolved\') ' +
        'should be x-element');
}, 'Unresolved custom element should be accessible by ' +
    'Document.querySelectorAll(\':unresolved\') in a loaded document');


test(function() {
    var doc = newHTMLDocument();

    HTML5_ELEMENTS.forEach(function(tagName) {
        if (HTML5_DOCUMENT_ELEMENTS.indexOf(tagName) === -1) {
            var obj = doc.createElement(tagName);
            var name = 'x-h-' + tagName;
            var id = 'x-h-' + tagName + '-id';
            if (HTML5_TABLE_ELEMENTS.indexOf(tagName) !== -1) {
                doc.body.innerHTML =
                    '<table>' +
                    '<' + tagName + ' id="' + id + '" is="' + name + '"></' + tagName + '>' +
                    '</table>';
            } else {
                doc.body.innerHTML =
                    '<' + tagName + ' id="' + id + '" is="' + name + '"></' + tagName + '>';
            }
            var queryResult = doc.querySelectorAll(':unresolved');

            assert_not_equals(queryResult, null,
                'Unresolved custom element should be accessible by :unresolved pseudoclass');
            assert_equals(queryResult.item(0).id, id,
                'ID of element returned by Document.querySelectorAll(\':unresolved\') ' +
                'should be ' + id);

            var proto = Object.create(obj.constructor.prototype);
            doc.registerElement(name, {prototype: proto, extends: tagName});
            var queryResult2 = doc.querySelectorAll(':unresolved');

            assert_equals(queryResult2.length, 0,
                'Registered custom element should not be accessible by :unresolved pseudoclass');
        }
    });
}, 'Test that Document.querySelectorAll(\':unresolved\') returns unresolved custom elements, ' +
    'extending HTML elements by IS attribute');


test(function() {
    var doc = newHTMLDocument();
    doc.body.innerHTML = '<x-i><a is="x-j"></a></x-i><x-k></x-k><b is="x-l"/>';
    var queryResult = doc.querySelectorAll(':unresolved');

    assert_equals(queryResult.length, 4,
        'All unresolved custom element should be accessible by :unresolved pseudoclass');

    var elementNames = [
        queryResult.item(0).localName,
        queryResult.item(1).localName,
        queryResult.item(2).localName,
        queryResult.item(3).localName];
    assert_array_equals(elementNames, ['x-i', 'a', 'x-k', 'b'],
        'Document.querySelectorAll(\':unresolved\') return unexpected result');

    var isAttributes = [
        queryResult.item(0).getAttribute('is'),
        queryResult.item(1).getAttribute('is'),
        queryResult.item(2).getAttribute('is'),
        queryResult.item(3).getAttribute('is')];
    assert_array_equals(isAttributes, [null, 'x-j', null, 'x-l'],
        'Document.querySelectorAll(\':unresolved\') return unexpected result');
}, 'Test Document.querySelectorAll(\':unresolved\') returns mix of custom elements of different types');
</script>
</body>
</html>
